#include <bits/stdc++.h>
using namespace std;
typedef long long LL;
int n,m,L,V,d[100005],v[100005],a[100005],p[100005];
vector<int> arr[1000005];
struct nd{
    int id,t,rnk;
    bool operator<(const nd& a) const{return t==a.t?id<a.id:t<a.t;}
};
set<nd> cur;
struct nd2{
    int id,t,rnk;
    bool operator<(const nd2& a) const{return id<a.id;}
};
set<nd2> cur2;
void add(int l,int r,int i){
    l=max(l,0);r=min(r,L);
    if (l<=r){arr[l].push_back(i);arr[r].push_back(-i);}
    return;
}
void solve(){
    int ans=0,ans2=0,idx=0;cur.clear();cur2.clear();
    scanf("%d%d%d%d",&n,&m,&L,&V);
    for (int i=1;i<=n;++i){scanf("%d%d%d",d+i,v+i,a+i);}
    for (int i=1;i<=m;++i){scanf("%d",p+i);}
    for (int i=0;i<=L;++i){arr[i].clear();}
    for (int i=1;i<=n;++i){
        if (a[i]){
            if (a[i]>0){
                add(d[i]+(((V*V-v[i]*v[i]))/(a[i]<<1)+1),L,i);
            }else{
                add(d[i],d[i]+((v[i]*v[i]-V*V)-1)/((-a[i])<<1),i);
            }
        }else if (v[i]>V){
            add(d[i],L,i);
        }
    }
    set<nd2>::iterator it;int posl,posr;
    for (int i=0;i<=L;++i){
        for (auto &&x : arr[i]){
            if (x>0){cur.insert({x,i,++idx});cur2.insert({x,i,idx});}else{
                x=-x;
                it=cur2.lower_bound({x,0,0});
                posl=lower_bound(p+1,p+1+m,it->t)-p;
                posr=upper_bound(p+1,p+1+m,i)-p-1;
                if (posl<=posr){++ans;}
                cur.erase({it->id,it->t,it->rnk});cur2.erase(it);
            }
        }
    }
    printf("%d %d\n",ans,m-(!(!ans)));
    return;
}
int main(){
    freopen("detect.in","r",stdin);
    freopen("detect.out","w",stdout);
    int T;scanf("%d",&T);++T;while (--T){solve();}
    return 0;
}
